from conf import Config
import logging
import socket
import session
from crypt import Crypt
import uuid

class UDPsocket():
    
    hostname = socket.gethostname()
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    __host = None
    __port = None
    __bufferSize = None
    
    def __init__(self):
        self.__host = Config.host
        self.__port = Config.port
        self.__bufferSize = Config.bufferSize
        server_address = ((self.__host, self.__port))
        try:
            logging.info('Binding UDP socket on port ' + str(self.__port) + ' ...')
            self.sock.bind(server_address)
            #ssl.wrap_socket(self.sock)
        except Exception as msg:
            logging.error('Unable to bind UDP socket . Error code: ' + str(msg))
            return
        logging.info('UDP socket binding successful.' + ' Hostname: ' + self.hostname + ' Port: ' + str(self.__port))

    def sendMessage(self, response, addr, crypted):
        mess = response
        if crypted == True:
            key = session.Session().getID(addr[0])
            key = uuid.UUID(key)
            key = key.bytes
            response = Crypt().encrypt(str(response), key)
            self.__sendBufferSize(response, addr)
            self.sock.sendto(response, addr)
        else:
            self.__sendBufferSize(response, addr)
            self.sock.sendto(bytes(str(response), 'utf8'), addr)
        logging.debug("Sent response: '" + str(mess) + "' to " + addr[0] + ':' + str(addr[1]))

    def __sendBufferSize(self, data, addr):
        if type(data) is bytes:
            size = len(data)
        else:
            size = len(bytes(str(data), 'utf-8'))
        response = {}
        response.update({'buffer':str(size)})
        self.sock.sendto(bytes(str(response), 'utf8'), addr)
        logging.debug("Sent buffer size: '" + str(response) + "' to " + addr[0] + ':' + str(addr[1]))
    
    def receivedMessage(self):
        return self.sock.recvfrom(self.__bufferSize)